<?php

require_once(dirname(__FILE__).'/../../lib/filelib.php');
require_once(dirname(__FILE__).'/module_resourcepage.php');
@include_once(dirname(__FILE__).'/custom_items.php');

/**
 * Class that represents a single item on the resource page. Also
 * includes fields from its base item if it had one.
 * @copyright &copy; 2006 The Open University
 * @author s.marshall@open.ac.uk
 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
 * @package resourcepage
 */
class resourcepage_item {

    /** Fields from database */
    private $fields;

    /** Owning container object */
    private $parent;

    /** Flags that are turned on/off (in main item). Map from flag => y/n */
    private $flags=array();
    /** Flags that are turned on in base item. Map from flag => y */
    private $baseflags=array();
    /** Files associated with this item */
    private $files=array();

    /** Format used for date display */
    const DATEFORMAT='j M Y';

    /** Used to indicate that display_header should print a resourcepage icon, instead of a file-type icon. */
    const RESOURCEPAGEICON='__resourcepageicon__';

    /**
     * Construct from relevant fields in database row.
     * @param object $parent Parent resourcepage_container
     * @param object $fields Database fields
     */
    public function __construct(&$parent, &$fields) {
        $this->parent =& $parent;
        $this->fields=$fields; // Copy
    }

    /**
     * Sets up flags from database.
     * @param string $flag Flag string
     * @param bool $value Flag value
     * @param bool $base True if flag is on base item, false if it's on main one
     */
    public function init_flag($flag,$value,$base=false) {
        if($value && strpos('tT1',substr($value,0,1))!==false) {
            if($base) {
                $this->baseflags[$flag]='y';
            } else {
                $this->flags[$flag]='y';
            }
        } else if(!$base) {
            $this->flags[$flag]='n';
        }
    }

    /**
     * Returns the resolved value of a flag as it applies to this item.
     * @param string $flag Flag ID string
     * @return boolean True if flag was set, false otherwise
     */
    public function get_resolved_flag($flag) {
        // If it's specified at the item directly...
        if(array_key_exists($flag,$this->flags)) {
            // Whether this is y or n, it overrides the base
            return $this->flags[$flag]=='y';
        }
        // Use the base value (if present)
        return
            array_key_exists($flag,$this->baseflags) &&
            $this->baseflags[$flag]=='y'; // It always should be but why not check
    }

    /**
     * @return array Array of all flags that are set by this or base item
     */
    public function get_set_flags() {
        $result=array();
        foreach($this->baseflags as $flag=>$value) {
            if($value=='y') {
                $result[$flag]='y';
            }
        }
        foreach($this->flags as $flag=>$value) {
            if($value=='y') {
                $result[$flag]='y';
            } else {
                unset($result[$flag]);
            }
        }
        return array_keys($result);
    }

    /**
     * Performs the necessary database operations to set the flag value
     * so that it ends up as desired. Does nothing if flag already has
     * that value.
     * @param string $flag Flag ID string
     * @param bool $on True for on, false for off
     */
    public function set_flag($flag,$on) {
        // Check for no change
        if($on==$this->get_resolved_flag($flag)) {
            return;
        }
        $module=module_resourcepage::$inst;
        // Get rid of any existing item flag
        if(array_key_exists($flag,$this->flags)) {
            $module->delete_item_flag($this->get_item(),$flag);
            unset($this->flags[$flag]);
        }
        // Did that fix it (same as base item)?
        if($on==$this->get_resolved_flag($flag)) {
            return;
        }
        // Obviously not, let's add one
        $module->add_item_flag($this->get_item(),$flag,$on);
        $this->flags[$flag]=$on?'y':'n';
    }

    /**
     * Sets up file from database.
     * @param object &$file resourcepage_file object
     */
    public function init_file(&$file) {
        $this->files[]=&$file;
    }

    /**
     * @return array List of all files (resourcepage_file).
     */
    public function get_files() {
        return $this->files;
    }

    /**
     * Obtains current value of field (from this item or from base).
     * @param string $fieldname Name of field
     * @return mixed Value of field in this item (if set) or in base (if present).
     */
    public function get_field($fieldname) {
        if(is_null($this->fields[$fieldname]) && array_key_exists('base'.$fieldname, $this->fields)) {
            return $this->fields['base'.$fieldname];
        } else {
            return $this->fields[$fieldname];
        }
    }

    /**
     * Obtains base value of field.
     * @param string $fieldname Name of field
     * @return mixed Value of field in base item (if present and set) or null.
     */
    public function get_base_field($fieldname) {
        return $this->fields['base'.$fieldname];
    }

    /**
     * Obtains current value of boolean field (from this item or from base).
     * Boolean fields are really integers because Moodle code guidelines
     * impose database type restrictions.
     * @param string $fieldname Name of field
     * @param bool $default Value to use if field isn't set
     * @return bool Field value
     */
    private function get_bool($fieldname,$default=false) {
        $value=$this->get_field($fieldname);
        return is_null($value) ? $default : ($value ? true : false);
    }

    /**
     * @return int Nesting level (1, 2, or 3) within containers.
     */
    private function get_nest_level() {
        for($nest=3;$nest>=1;$nest--) {
            if(!is_null($this->fields['hidden'.$nest])) {
                return $nest;
            }
        }
        // Shouldn't get here
        throw new Error('Unexpected state from database query');
    }

    /**
     * @return bool True if item is hidden
     */
    private function is_hidden() {
        return
            (bool)$this->fields['hidden1'] ||
            (bool)$this->fields['hidden2'] ||
            (bool)$this->fields['hidden3'];
    }

    /**
     * @return bool True if item is individually hidden i.e. it's this item's
     *   hidden field that is causing it
     */
    private function is_individually_hidden() {
        return (bool)$this->fields['hidden'.$this->get_nest_level()];
    }

    /**
     * Sets item hidden field value to relevant container item value
     * @param None
     * @return None
     */
    public function set_item_field_hidden() {
        $this->fields['hidden'] = $this->is_individually_hidden();
    }

    /**
     * Displays as HTML.
     * @param object $course Object representing row from Moodle course table
     * @param object $cm Course module table row
     * @param boolean $editmode True when page is in edit mode (or edit item mode)
     * @param boolean $edititem Set to 'item' ID when page is in edit item mode, null otherwise
     * @param boolean $ignored Unnecessary parameter required so it matches the resourcepage_container
     *   method
     * @param boolean $itemcontrols If false, an item even in edit mode should not be editable (though
     *   it should still display admin information)
     * @param boolean $showinfo If true, shows information about items
     */
    public function display($course,$cm,$editmode=false,$edititem=null,$ignored,$itemcontrols=true,$parent=null,$parentobj=null,$indeleted=false,$showinfo=false,$first=false) {

        global $CFG;
        // Get info we need elsewhere
        $hidden=$this->is_hidden() || $this->get_bool('forcehide');
        $editingitem=$edititem == $this->get_field('item');
        $itemid=$this->fields['item'];
        $sesskey=sesskey();
        $parentcontainer=$this->parent->get_container();
        $itemtype=$this->get_field('itemtype');
        $filewithnofiles=$itemtype=='file' && count($this->files)==0;
        $weblinkwithnolink=$itemtype=='weblink' && trim($this->get_field('weblink')) == 'http://';
        $live=$this->get_field('livedate');
        $remove=$this->get_field('removedate');
        $livetime=module_resourcepage::convert_date($course->startdate,$live);
        $removetime=module_resourcepage::convert_date($course->startdate,$remove);
        $beforelivedate = (!is_null($live) && time() < $livetime);
        $afterremovedate = (!is_null($remove) && time() >= $removetime);
        $showto=$this->get_field('showto');
        if($showto==null) {
            $showto='';
        }
        $rightsnotconfirmed = $itemtype == 'file' 
            ? !$this->get_field('rights') : false;

        // handles the setting up of copy/move check boxes
        if($itemcontrols) {
            if($edititem == null) {
                $edit = $editmode;
            } else {
                $edit = false;
            }
        } else {
            $edit = false;
        }

        // Check if item should not be displayed
        $notdisplayed = $this->is_hidden_from_students($course);

        // For students, not-displayed items really aren't displayed!
        if(!$showinfo && $notdisplayed) {
            return;
        }
        // Begin item
        print '<div class="rp_item'.($notdisplayed && !$editingitem ? ' rp_hidden' : '').
          ($first ? ' rp_first' : '').'">';

        // Show controls (unless some item, inc. this one, is being edited)
        if($editmode && $this->get_bool('editable',true) && $itemcontrols && !$edititem) {
            $draghandlealt=get_string('draghandle','resourcepage');
            $pixpath=$CFG->pixpath;
            $update=get_string('update');
            $deletealt=get_string('delete');
            $showhide=$this->is_individually_hidden() ? 'show' : 'hide';
            $showhidealt=get_string($showhide);
            $extraclass=$itemtype=='placeholder' ? ' rp_twoicons' : '';
            print
"<div class='rp_controls'>".
"<div class='rp_draghandle$extraclass' id='rp_draghandle_{$parentcontainer}_$itemid'><img onmousedown='return false' ondragstart='return false' src='draghandle.png' alt='$draghandlealt' tabindex='0' /></div><div class='rp_stdicons'>".
    "<form method='post' action='containeritem.php'><div>".
    "<input type='hidden' name='scrollpos' value='' />".
    "<input type='hidden' name='sesskey' value='$sesskey' />".
    "<input type='hidden' name='id' value='$cm->id' />".
    "<input type='hidden' name='container' value='$parentcontainer' />".
    "<input type='hidden' name='item' value='$itemid' />";
            if($itemtype!='placeholder') {
                print
    "<a href='view.php?id=$cm->id&amp;item=$itemid' class='scrollpos'>".
        "<img src='$pixpath/t/edit.gif' alt='$update' />".
    "</a>";
                if ($itemtype == 'text' || $itemtype == 'weblink' || $itemtype == 'file' || $itemtype == 'crosslink') {
                    print
    "<input class='rp_img' name='actioncopy' type='image' src='$pixpath/t/copy.gif' alt='".get_string('copy','resourcepage')."' />";
                }
                if ($itemtype == 'file' && !$indeleted) {
                    print "<input class='rp_img' name='main' value='main' type='image' src='$pixpath/t/calendar.gif' alt='".get_string('copytomain','resourcepage')."' />";
                }
                print
    "<input class='rp_img' name='action$showhide' type='image' src='$pixpath/t/$showhide.gif' alt='$showhidealt' />";
            } else {
                $phdisplay=module_resourcepage::$inst->get_placeholder_display_details(
                    $this->fields['placeholder'],$itemid);
                if(!$phdisplay) {
                    throw new Exception('Placeholder type unknown');
                }

                if($phdisplay->editable) {
                    print
                        '<div style="height:6px"></div>'.
                        "<a href='editextension.php?sesskey={$sesskey}&amp;id=$cm->id&amp;extension={$phdisplay->extension}&amp;placeholderitemid=$itemid&amp;placeholder={$this->fields['placeholder']}' class='scrollpos'>".
                            "<img src='$pixpath/t/edit.gif' alt='$update' />".
                        "</a>";
                } else {
                    print '<div style="height:13px"></div>';
                }
            }

            // Restrict deletion of placeholder items on capability
            $context = get_context_instance(CONTEXT_MODULE, $cm->id);
            if ($itemtype != 'placeholder' || has_capability('mod/resourcepage:deleteplaceholders',$context)) {
                print
    "<input class='rp_img' name='actiondelete' type='image' src='$pixpath/t/delete.gif' alt='$deletealt' />";
            }
            print
    "</div></form>".
"</div>".
"</div>";
        }

        // Begin main part
        print '<div class="rp_mainbit">';

        if($editingitem) {
            print <<<HTMLEND
<form class="rp_edititem" method="post" enctype="multipart/form-data" action="edititem.php" id="rp_edititemform" name="edititemform">
<input type="hidden" name="sesskey" value="$sesskey" />
<input type="hidden" name="id" value="$cm->id" />
<input type="hidden" name="container" value="$parentcontainer" />
<input type="hidden" name="item" value="$itemid" />
<input type="hidden" name="itemtype" value="$itemtype" />
<input type="hidden" name="deletefile" value="" id="rp_deletefile" />
<input type="hidden" name="scrollpos" value="" />
<input type="hidden" name="actiondelete_x" value="1" />
HTMLEND;
        }

        // Do main part depending on type
        $preventlinks=$edititem || ($notdisplayed && !$editmode);
        switch($itemtype) {
            case 'weblink' :
                $this->display_weblink($editingitem,$preventlinks, $edit, $indeleted);
                break;
            case 'file' :
                $this->display_file($editingitem,$course->id,$preventlinks, $cm, $edit, $indeleted);
                break;
            case 'placeholder' :
                if($editmode) {
                    if(empty($phdisplay)) {
                        $phdisplay=module_resourcepage::$inst->get_placeholder_display_details(
                            $this->fields['placeholder'],$itemid);
                        if(!$phdisplay) {
                            throw new Exception('Placeholder type unknown');
                        }
                    }
                    $this->display_placeholder($course->id,$phdisplay, $indeleted);
                }
                break;
            case 'text' :
                $this->display_text($editingitem, $edit, $indeleted);
                break;
            case 'crosslink' :
                $this->display_crosslink($editingitem,$course->id,$cm->instance,$preventlinks, $edit, $indeleted);
                break;
            case 'forumlink' :
                if (function_exists('display_forumlink')) {
                    display_forumlink($editmode,$editingitem,$course->id,$preventlinks, $this, $edit, $indeleted);
                }
                break;
            case 'reference' :
                $this->display_reference($editingitem,$preventlinks, $edit, $indeleted);
                break;
            default:
                throw new Exception('Unknown item type in database: '.
                    $this->get_field('itemtype'));
        }

        // Do save/cancel buttons if editing
        if($editingitem) {
            // Do flags
            if($itemtype=='file' || $itemtype=='weblink') { // Flags only apply to these types
                $labeltext=get_string('flags','resourcepage');
                print <<<HTMLEND
<div class="rp_label rp_label_dropdown">$labeltext
HTMLEND;
                helpbutton('flags', get_string('help_flags', 'resourcepage'), 'resourcepage');
                print <<<HTMLEND
</div>
<div class="rp_field rp_field_flags">
HTMLEND;
                $module=module_resourcepage::$inst;
                $allflags=$module->get_available_flags();
                foreach($allflags as $flag) {
                    if ($module->is_item_flag($itemtype, $flag) &&
                        $module->user_can_edit_item_flag($flag)) {
                        $choices=array();
                        $choices[1] = $module->get_flag_text($flag,true);
                        $choices[0] = $module->get_flag_text($flag,false);
                        choose_from_menu($choices,'flag_'.$flag,
                            $this->get_resolved_flag($flag) ? 1 : 0,'');
                    }
                }
                echo '</div>';
            }

            // get rights clearance for files
            if($itemtype=='file') {
                $possiblerights = array(1 => get_string('yes'), 0 => get_string('no') );
                $this->print_dropdown('rights', $this->get_field('rights'), $possiblerights);
            }

            // Do live/remove date
            $livedatestring=get_string('livedate','resourcepage');
            $livedatechecked=is_null($this->get_field('livedate')) ? '' : 'checked="checked"';
            $removedatestring=get_string('removedate','resourcepage');
            $removedatechecked=is_null($this->get_field('removedate')) ? '' : 'checked="checked"';
            echo <<<HTMLEND
<script type="text/javascript" language="javascript">
    var livedateitems = ['livedateday','livedatemonth','livedateyear'];
    var removedateitems = ['removedateday','removedatemonth','removedateyear'];
</script>
<div class="rp_label">$livedatestring:</div>
<div class="rp_field">
    <input name="livedateenable" type="checkbox"
      onclick="return lockoptions('edititemform', 'livedateenable', livedateitems)"
      $livedatechecked />
HTMLEND;

            $sign=$this->get_field('livedate') < 0 ? '' : '+';
            $time=module_resourcepage::convert_date($course->startdate,$this->get_field('livedate'));
            print_date_selector("livedateday", "livedatemonth", "livedateyear", $time);
            helpbutton('liveremovedate', get_string('livedate', 'resourcepage'), 'resourcepage');

            echo <<<HTMLEND
</div>
<div class="rp_label">$removedatestring:</div>
<div class="rp_field">
    <input name="removedateenable" type="checkbox"
      onclick="return lockoptions('edititemform', 'removedateenable', removedateitems)"
      $removedatechecked />
HTMLEND;


            $sign=$this->get_field('removedate') < 0 ? '' : '+';
            $time=module_resourcepage::convert_date($course->startdate,$this->get_field('removedate'));
            print_date_selector("removedateday", "removedatemonth", "removedateyear", $time);
            helpbutton('liveremovedate', get_string('removedate', 'resourcepage'), 'resourcepage');

            echo '</div>';



            echo '<script type="text/javascript">';

            if (!$livedatechecked) echo "lockoptions('edititemform', 'livedateenable', livedateitems);";
            if (!$removedatechecked) echo "lockoptions('edititemform', 'removedateenable', removedateitems);";

            echo '</script>';

            // Do showto field
            // Only if we are using auth ids
            if (defined('AUTH_SAMS') && AUTH_SAMS == $CFG->auth) {
            $showtostring=get_string('showto', 'resourcepage');
            echo <<<HTMLEND
<div class="rp_label">$showtostring:</div>
<div class="rp_field">
    <input name="showto" type="text" size="30" value="$showto"/>
HTMLEND;
            helpbutton('showto', get_string('help_showto', 'resourcepage'), 'resourcepage');
            echo '</div>';
            }

            // Save/cancel buttons
            echo <<<HTMLEND
<div class="rp_clear"></div>
<div class="rp_savecancel">
<input type="submit" value="Save changes" />
<input type="button" value="Cancel" onclick="canceledit()" />
</div>
</form>
HTMLEND;
        }

        // If in editing mode, display optional extra info
        if($showinfo) {
            if($hidden) {
                echo '<div class="rp_extra rp_hidden">'.
                    get_string('adminmsg_hidden','resourcepage').'</div>';
            }
            if($showto) {
                echo '<div class="rp_extra rp_hidden">'.
                    get_string('adminmsg_showto','resourcepage',$showto).'</div>';
            }
            if($beforelivedate) {
                echo '<div class="rp_extra rp_hidden">'.
                    get_string('adminmsg_beforelivedate','resourcepage',
                    date(self::DATEFORMAT, $livetime)).'</div>';
            }
            if($afterremovedate) {
                echo '<div class="rp_extra rp_hidden">'.
                    get_string('adminmsg_afterremovedate','resourcepage',
                    date(self::DATEFORMAT, $removetime)).'</div>';
            } else if($remove) {
                echo '<div class="rp_extra rp_info">'.
                    get_string('adminmsg_removedatepresent','resourcepage',
                    date(self::DATEFORMAT, $removetime)).'</div>';
            }
            if($filewithnofiles) {
                echo '<div class="rp_extra rp_hidden">'.
                    get_string('adminmsg_hiddennofiles','resourcepage').'</div>';
            }
            if($weblinkwithnolink) {
                echo '<div class="rp_extra rp_hidden">'.
                    get_string('adminmsg_hiddennolink','resourcepage').'</div>';
            }
            if($plugininfo=$this->get_field('plugininfo')) {
                echo '<div class="rp_extra rp_info">'.htmlspecialchars($plugininfo).'</div>';
            }
            if(count($this->files) > 0 && !empty($this->files[0]->extrainfo)) {
                echo '<div class="rp_extra rp_info">'.htmlspecialchars($this->files[0]->extrainfo).'</div>';
            }
            if($rightsnotconfirmed) {
                echo '<div class="rp_extra rp_rightsnotconfirmed">'.
                    get_string('adminmsg_rightsnotconfirmed','resourcepage').'</div>';
            }

        }

        // Close item
        echo '</div><div class="rp_clear"></div></div>';
    }

    /**
     * Returns the bit of code that goes after the title in brackets.
     * @return string That code as HTML (including the brackets).
     */
    private function get_item_details($cm=NULL) {
        $module=module_resourcepage::$inst;
        $itemtype=$this->get_field('itemtype');

        $info='';
        if($itemtype=='file' && count($this->files)==1) {
            $file=$this->files[0];
            $typedesc=get_mimetype_description($file->get_mime_type());
            $info.=display_size($file->get_size()).' '.$typedesc;
        }
        $printondemand = false;
        foreach($this->get_set_flags() as $flag) {
            // Does it want to add text?
            $printondemand |= ($flag == 'printondemand');
            if($extrainfo=$module->get_flag_extrainfo($flag)) {
                if($info!='') $info.='; ';
                $info.=$extrainfo;
            }
        }

        // Get print on demand button and associated info if required
        $podinfo = '';
        if ($printondemand && function_exists('get_pod_info') && count($this->files)>0) {
            $podinfo = get_pod_info($this->get_field('title'), $this->files, $cm);
        }

        if($info=='' && $podinfo == '') {
            return '';
        }
        return ' <span class="rp_filedetails">('.$info.')</span>'.$podinfo;
    }

    private function get_icons($main,$includeflags=true,$crosslinkicon=false) {
        global $CFG;
        // Main icon is only decoration, doesn't need alt
        $return='';
        if ($main) {
            if($main == self::RESOURCEPAGEICON) {
                $iconpath = '/mod/resourcepage/icon.gif';
            } elseif($crosslinkicon) {
                $iconpath = '/mod/'.$main.'/icon.gif';
            } else {
                $iconpath = '/f/'.$main;
            }
            $return.='<img src="'.$CFG->pixpath.$iconpath.'" alt="" width="16" height="16"/>';
        }
        $hasflags=false;
        if($includeflags) {
            $module=module_resourcepage::$inst;
            foreach($this->get_set_flags() as $flag) {
                // Does it want to add icon?
                $icondetails=$module->get_flag_icon_info($flag);
                if($icondetails->exists) {
                    $return.='<img src="'.$icondetails->src.'" alt="'.
                        $icondetails->alt.'"/>';
                    $hasflags=true;
                }
            }
        }
        if($return) {
            return '<span class="rp_icon'.(!$hasflags ? ' rp_noflags' : '').(!$main ? ' rp_nomain' : '').'">'.$return.'</span>';
        } else {
            return '<span class="rp_noicon"></span>';
        }
    }

    function display_header($mainicon,$iconflags,$url,$content,$nolinks,$istext=false, $cm=NULL, $hlevel='h3',
        $newwindow=false, $edit=false, $indeleted=false, $crosslinkicon=false,$reference=false) {
        // Ensure URL is safe
        if(preg_match('/[<>\'"]/',$url)) {
            $url='http://in.valid/url/';
        }
        if(!$content) {
            // Don't print empty titles
            return;
        }
        print '<'.$hlevel.' class="rp_header'.($istext? ' rp_textitem' : '').'">';
        $icons=$this->get_icons($mainicon,$iconflags,$crosslinkicon);
        if($nolinks || !$url) {
            print $icons.'<span class="rp_title">'.$content.'</span>';
        } else {
            $target=$newwindow ? ' target="_blank"' : '';
            $newwindowtext=$newwindow ? ' <small>('.get_string('opensinnewwindow','resourcepage').')</small>' : '';
            print '<a href="'.htmlspecialchars($url).'"'.$target.'>'.$icons.'<span class="rp_title">'.$content.'</span>'.$newwindowtext.'</a>';
        }
        print $this->get_item_details($cm);

        $itemid=$this->fields['item'];

        if($edit && !$indeleted) {
            $parentcontainer=$this->parent->get_container();
            print '<input type="checkbox" id="multiselect_'.$itemid.'" name="copyitems" value="'.$parentcontainer.'_'.$itemid.'" onclick="checkBoxes(this, \'multiselect_\',document.getElementById(\'multi_idlist\'));" />';
        }
        //special case for refrence items - display checkbox for exporting selected refs
        global $resourcepage;
        if(!$edit && !$indeleted && $reference && $resourcepage->exportrefs==1) {
            print '<input type="checkbox" id="refmultiselect_'.$itemid.'" name="selref" value="'.$itemid.'" title="'.get_string('reference_checkboxtitle','resourcepage').'"/>';
        }

        print '</'.$hlevel.'>';

    }

    /**
     * @param string $url URL for link
     * @return string The appropriate image, e.g. 'web.gif', to use as icon
     */
    function get_link_icon($url) {
        if(preg_match('/\.pdf(\?.*)$/',$url)) {
            return 'pdf.gif';
        } else {
            return 'web.gif';
        }
    }

    /**
     * Displays the main content of a web link item.
     * @param bool $editing If true, display fields for inline editing of this item.
     * @param bool $otheritem If true, turn off links as other item is being edited
     */
    private function display_weblink($editing,$otheritem, $edit=false, $indeleted = false) {
        $backbroken=strpos($this->get_field('options'),'B')!==false ? 1 : 0;
        if(!$editing) {
            $url=$this->get_field('weblink');
            $url=$this->check_weblink($url);
            $this->display_header($this->get_link_icon($url),true,$url,
                    self::get_title_as_html($this->get_field('title')),$otheritem,false,null,'h3',$backbroken && preg_match('/MSIE.*Windows/',$_SERVER['HTTP_USER_AGENT']),$edit, $indeleted);
                // When the back button is broken, and the user is running IE, we make the
                // link open in the new window.

            $this->display_description();
        }
        else {
            $this->print_editing_title('weblink');
            $this->print_text_input('title',$this->get_field('title'));
            $this->print_text_input('weblink',$this->get_field('weblink'));
            $this->print_html_area('description',$this->get_field('description'));
            if(isadmin()) {
                $options=array();
                $options[0]=get_string('backbuttonok','resourcepage');
                $options[1]=get_string('backbuttonbroken','resourcepage');
                $this->print_dropdown('backbroken',$backbroken,$options);
            }
        }
    }
    
/**
     * Displays the main content of a reference item.
     * @param bool $editing If true, display fields for inline editing of this item.
     * @param bool $otheritem If true, turn off links as other item is being edited
     */
    private function display_reference($editing,$otheritem, $edit=false, $indeleted = false) {
        $backbroken=strpos($this->get_field('options'),'B')!==false ? 1 : 0;
        if(!$editing) {
            $url=$this->get_field('weblink');
            $url=$this->check_weblink($url);
            
            $title=htmlentities($this->get_field('title'),ENT_NOQUOTES,'UTF-8',false);
            $title=str_replace('&lt;','<',$title);
            $title=str_replace('&gt;','>',$title);
            //replace any non-semantic deprecated tags (thanks to clean_param)
            $title=str_replace('<i>','<span style="font-style:italic">',$title);
            $title=str_replace('</i>','</span>',$title);
            if(stripos($title,'<b>')!==false){
                $title=str_replace('<b>','<span style="font-weight:bolder">',$title);
                $title=str_replace('</b>','</span>',$title);
            }
            
            if($url===null){
                $this->display_header(null,true,null,
                $title ,$otheritem,false,null,'h3',$backbroken && preg_match('/MSIE.*Windows/',$_SERVER['HTTP_USER_AGENT']),$edit, $indeleted,false,true); 
            }else{
                $this->display_header($this->get_link_icon($url),true,$url,
                $title ,$otheritem,false,null,'h3',$backbroken && preg_match('/MSIE.*Windows/',$_SERVER['HTTP_USER_AGENT']),$edit, $indeleted,false,true);
            // When the back button is broken, and the user is running IE, we make the
            // link open in the new window.  
            }
            
            
           

            $this->display_description();
        }
        else {
            $this->print_editing_title('reference');
            $this->print_text_input('title',$this->get_field('title'));
            $this->print_text_input('weblink',$this->get_field('weblink'));
            $this->print_html_area('description',$this->get_field('description'));
            if(isadmin()) {
                $options=array();
                $options[0]=get_string('backbuttonok','resourcepage');
                $options[1]=get_string('backbuttonbroken','resourcepage');
                $this->print_dropdown('backbroken',$backbroken,$options);
            }
        }
    }

    /**
     * Displays the main content of a forum link
     */

    /** Removes the limited html that is permitted in title fields */
    private static function get_title_as_text($title) {
        return preg_replace('^</?cite>^','',$title);
    }
    /** Escapes html except the limited html that is permitted in title fields */
    function get_title_as_html($title) {
        return preg_replace('^&lt;(/?cite)&gt;^','<$1>',htmlspecialchars($title));
    }

    /**
     * Displays the main content of a file item.
     * @param bool $editing If true, display fields for inline editing of this item.
     * @param int $courseid ID of course
     * @param bool $otheritem If true, turn off links as other item is being edited
     */
    private function display_file($editing,$courseid,$otheritem, $cm=NULL, $edit, $indeleted = false) {


        if(!$editing) {
            // OK are there multiple formats?
            $gotmultiple=count($this->files) > 1;
            $gotany=count($this->files) > 0;

            // For multiple files (and if file isn't loaded yet) we make the title not be a link and have no icon
            if($gotmultiple || !$gotany) {
                $this->display_header(
                    false,true,
                    false,
                    self::get_title_as_html($this->get_field('title')),
                    $otheritem, false, $cm, 'h3', false, $edit, $indeleted);
            } else { // Single files get icon and link
                $file=$this->files[0];
                $this->display_header(
                    mimeinfo_from_type("icon",$file->get_mime_type()),true,
                    $this->get_link_path($courseid,$file),
                    self::get_title_as_html($this->get_field('title')),
                    $otheritem, false, $cm, 'h3', false, $edit, $indeleted);
            }

            // Description comes next
            $this->display_description();

            // If there were multiple files then we next print the icons and file links
            if($gotmultiple) {
                $this->print_files($courseid,false,$otheritem);
            }

        }
        else {
            $this->print_editing_title('file');
            $this->print_text_input('title',$this->get_field('title'));
            $this->print_html_area('description',$this->get_field('description'));

            print
                '<div class="rp_label rp_label_files">'.
                get_string('field_files','resourcepage');
            helpbutton('files', get_string('help_files', 'resourcepage'), 'resourcepage');
            print '</div>'.
                '<div class="rp_field rp_field_files">';
            $this->print_files($courseid,true);
            print
                '<div class="rp_add">'.get_string('addnewfile','resourcepage').
                ' <input type="file" name="addfile" />'.
                '</div></div>';
        }
    }

    function print_editing_title($type) {
        print '<h3><span class="rp_editlabel">'.get_string('editing_'.$type,'resourcepage').
            '</span></h3>';
    }

    private function get_link_path($courseid,$file) {
        return '../../file.php/'.$courseid.'/!via/resourcepage/'.$this->get_item().'/'.$file->get_filepath();
    }

    private function escape_both_quotes($string) {
        return str_replace('"','\"',str_replace("'","\\'",$string));
    }

    private function print_files($courseid,$withdelete=false,$hidelinks=false) {
        global $CFG;
        print '<ul class="rp_files">';
        $index=0;
        foreach($this->files as $file) {
            $typedesc=get_mimetype_description($file->get_mime_type(),true);
            print '<li>'.
                (!$hidelinks ? '<a  href="'.$this->get_link_path($courseid,$file).'">' : '').
                $this->get_icons(mimeinfo_from_type("icon",$file->get_mime_type()),false).
                '<span class="rp_title">'.$typedesc.'</span>'.(!$hidelinks ? '</a>' : '').
                ' <span class="rp_filedetails">('.display_size($file->get_size()).')</span>';
            if($withdelete && !$file->get_from_base()) {
                $deletejs='window.deletefile(\''.$this->escape_both_quotes($file->get_filepath()).'\')';
                print ' <img tabindex="0" onclick="'.$deletejs.'" onkeypress="'.$deletejs.'" '.
                    'src="'.$CFG->pixpath.'/t/delete.gif" />';
            }
            print
                '</li>';
            $index++;
        }
        print '</ul>';
    }



    private function display_description() {
        $description=$this->get_field('description');
        // If it's empty (or has nothing except tags), don't output it
        if(preg_replace('/\s|<.*?>/','',$description)!='') {
            // Disabling smilies
            $options = new stdClass;
            $options->smiley = false;
            $options->noclean = true;
            print
                '<div class="rp_description">'.
                format_text($this->get_field('description'),FORMAT_HTML, $options).
                '</div>';
        }
    }

    /**
     * Displays the main content of a text item.
     * @param bool $editing If true, display fields for inline editing of this item.
     */
    function display_text($editing, $edit=false, $indeleted = false) {

        // Pick up Heading level and styles
        $itemlevel = $this->fields['headinglevel'];
        $styles = explode(',', get_string('styleattrs', 'resourcepage'));
        if (empty($itemlevel) || $itemlevel >= count($styles)) {
            $itemlevel = 0;
        }

        if(!$editing) {
            $this->display_header(false,false,false,
                self::get_title_as_html($this->get_field('title')),false,true,
                NULL, $styles[$itemlevel], false, $edit, $indeleted);
            $this->display_description();
        }
        else {
            $this->print_editing_title('text');
            $this->print_text_input('title',$this->get_field('title'));

            $labeltext=get_string('styles','resourcepage');
            print '<div class="rp_label rp_label_dropdown">'.$labeltext;
            helpbutton('styles', get_string('help_styles', 'resourcepage'), 'resourcepage');
            print '</div><div class="rp_field rp_field_flags">';
            $choices = explode(',', get_string('stylechoices', 'resourcepage'));
            choose_from_menu($choices,'headinglevel', $itemlevel, '');
            echo '</div>';

            $this->print_html_area('description',$this->get_field('description'));
        }
    }

    /**
     * Displays the main content of a crosslink item.
     * @param bool $editing If true, display fields for inline editing of this item.
     * @param int $courseid ID of course
     * @param int $moduleid ID of this module
     * @param bool $otheritem If true, turn off links as other item is being edited
     */
    function display_crosslink($editing,$courseid,$moduleid,$otheritem, $edit, $indeleted = false) {
        global $COURSE, $CFG;
        $course = $COURSE;
        $modinfo = get_fast_modinfo($course);
        if(!$editing) {
            $cmid = (int)($this->get_field('crosslink'));
            if(!array_key_exists($cmid, $modinfo->cms)) {
                // Oh dear it is actually on a different course
                if ($cmid) {
                    $course = get_record_sql("
SELECT 
    c.* 
FROM 
    {$CFG->prefix}course_modules cm
    INNER JOIN {$CFG->prefix}course c ON c.id = cm.course
WHERE
    cm.id=$cmid");
                } else {
                    $course = false;
                }
                if (!$course) {
                    $this->display_header(null, false,
                        '','(Link here is not displayed because its target has been deleted)', $otheritem,
                        false, null, 'h3', false, $edit, $indeleted, null);
                    $this->display_description();
                    
                    return;
                }
                $modinfo = get_fast_modinfo($course);
            }
            $cm = $modinfo->cms[$cmid];
            $crosslinktitle = $cm->name;
            $modurl = $CFG->wwwroot.'/mod/'.$cm->modname.'/view.php?id='.$cmid;
            if (!empty($cm->icon)) {
                $crosslinkicon = $cm->icon;
            } else {
                $crosslinkicon = $cm->modname."/icon.gif";
            }
            $icon = $cm->modname;
            $extrahtml = '';
            if ($cm->modname == 'forum') {
                require_once($CFG->dirroot . '/mod/forum/lib.php');
                if ($unread = forum_tp_count_forum_unread_posts($cm, $course)) {
                    $extrahtml = ' <span class="unread">';
                    if ($unread == 1) {
                        $extrahtml .= get_string('unreadpostsone', 'forum');
                    } else {
                        $extrahtml .= get_string('unreadpostsnumber', 'forum', $unread);
                    }
                    $extrahtml .= '</span>';
                }
            }

            // This code copied (modified) from course/lib.php
            static $forumng_forums;
            if ($cm->modname == 'forumng') {
                // Lazy-initialise forums static only once we encounter at least
                // one forum.
                if (!$forumng_forums) {
                    require_once($CFG->dirroot . '/mod/forumng/forum.php');
                    if (forum::enabled_read_tracking()) {
                        $forumng_forums = forum::get_course_forums(
                            $course, 0, forum::UNREAD_BINARY);
                    } else {
                        $forumng_forums = array();
                    }
                }

                // If current forum is listed, check whether it's unread or not
                if (array_key_exists($cm->instance, $forumng_forums)) {
                    if ($forumng_forums[$cm->instance]->has_unread_discussions()) {
                        $extrahtml = '<span class="unread">' .
                            get_string('hasunreadposts', 'forumng') . '</span>';
                    }
                }
            }

            $this->display_header($icon,false,
                $modurl,htmlspecialchars($crosslinktitle).$extrahtml,$otheritem,
                false, null, 'h3', false, $edit, $indeleted, $crosslinkicon);

                // parameters " false, null, 'h3', false, $edit " added
                // to function call display header above

            $this->display_description();
        }
        else {
            $this->print_editing_title('crosslink');
            $module=module_resourcepage::$inst;
            $modlist = array();
            foreach ($modinfo->cms as $mod) {
                if($mod->modname != 'repeatactivity' && $mod->modname != 'label' && $mod->instance != $moduleid) {
                    $modlist[$mod->id] = $mod->name.html_entity_decode(" &#xb7; &#xb7; &#xb7; ",ENT_QUOTES,'UTF-8').get_string('modulename', $mod->modname);
                }
            }
            $this->print_dropdown('linkto',$this->get_field('crosslink'),
                $modlist);

            $this->print_html_area('description',$this->get_field('description'));
        }
    }

    /**
     * Displays the main content of a placeholder item.
     * @param object $display Placeholder display details obtained using get_placeholder_display_details
     */
    function display_placeholder($courseid,$display, $indeleted = false) {
        $placeholder=$this->get_field('placeholder');
        $this->display_header(false,false,false,
            '<span class="rp_placetitle">Placeholder: </span>'.htmlspecialchars($display->title),
            false);
        if(preg_replace('/\s|<.*?>/','',$display->description)!='') {
            // Disabling smilies
            $options = new stdClass;
            $options->smiley = false;
            print
                '<div class="rp_description">'.
                format_text($display->description,FORMAT_HTML, $options).
                '</div>';
        }
        echo '<div class="rp_extra">'.
            get_string('adminmsg_placeholder','resourcepage').'</div>';
    }


    /**
     * @return int Item ID
     */
    public function get_item() {
        return $this->fields['item'];
    }

    function print_text_input($field,$value,$fill=true) {
        $labeltext=get_string("field_$field",'resourcepage');
        $htmlvalue=htmlspecialchars($value);
        $inputclass=$fill? 'class="rp_fillwidth"' : '';

        print <<<HTMLEND
<div class="rp_label rp_label_text">$labeltext</div>
<div class="rp_field rp_field_text"><input type="text" $inputclass name="$field" value="$htmlvalue" /></div>
HTMLEND;

        if(array_key_exists($field,$this->fields)) {
            if(!is_null($this->fields[$field]) && !is_null($this->fields['base'.$field])) {
                print '<div class="rp_basevalue">'.get_string('basevalue','resourcepage').' <span>'.
                    $this->fields['base'.$field].'</span></div>';
            }
        }

    }

    /**
     * Prints a dropdown list.
     * @param string $field Label name for field and form control
     * @param string $value Currently selected ID
     * @param array $values Associative array of ID (value=) to text (content of option element)
     */
    function print_dropdown($field,$value,$values) {

        $labeltext=get_string("field_$field",'resourcepage');
        $helptext=get_string("help_$field", 'resourcepage');
        if(strpos('[[',$helptext)!==0) {
            $helpbit=helpbutton($field, $helptext, 'resourcepage',true,false,'',true);
        } else {
            $helpbit='';
        }

        print <<<HTMLEND
<div class="rp_label rp_label_dropdown">$labeltext$helpbit</div>
<div class="rp_field rp_field_dropdown"><select name="$field">
HTMLEND;
        foreach($values as $id=>$text) {
            print '<option value="'.$id.'"'.
                ($value==$id ? ' selected="selected"' : '').'>'.htmlspecialchars($text).'</option>';
        }

        print '</select></div>';
    }

    function print_html_area($field,$value,$rows=10) {
        $labeltext=get_string("field_$field",'resourcepage');
        $usehtmleditor=can_use_html_editor();

        print '<div class="rp_label rp_label_html">'.$labeltext.'<br />';
        helpbutton('writing', get_string('helpwriting'), 'moodle', true, true);
        print '<br />';
        if ($usehtmleditor) {
           helpbutton('richtext', get_string('helprichtext'), 'moodle', true, true);
        } else {
           emoticonhelpbutton('form', 'description');
        }
        print '</div><div class="rp_field rp_field_html">';
        print_textarea($usehtmleditor, $rows, 10, 0, 0, $field, $value);
        print '</div>';

        if ($usehtmleditor) {
            use_html_editor($field);
        }
    }

    /**
     * @return array List of field names that defer to a base item (i.e. are set null)
     */
    private function get_deferring_fields() {
        $result=array();
        if(is_null($this->fields['editable'])) {
            $result[]='editable';
        }
        if(is_null($this->fields['livedate'])) {
            $result[]='livedate';
        }
        if(is_null($this->fields['removedate'])) {
            $result[]='removedate';
        }
        if(is_null($this->fields['showto'])) {
            $result[]='showto';
        }
        if(is_null($this->fields['title'])) {
            $result[]='title';
        }
        if(is_null($this->fields['description'])) {
            $result[]='description';
        }
        if(is_null($this->fields['plugininfo'])) {
            $result[]='plugininfo';
        }
        if(is_null($this->fields['forcehide'])) {
            $result[]='forcehide';
        }
        if(is_null($this->fields['weblink'])) {
            $result[]='weblink';
        }
        if(is_null($this->fields['crosslink'])) {
            $result[]='crosslink';
        }
        if(is_null($this->fields['headinglevel'])) {
            $result[]='headinglevel';
        }
        if(is_null($this->fields['options'])) {
            $result[]='options';
        }
        if(is_null($this->fields['rights'])) {
            $result[]='rights';
        }
        if(is_null($this->fields['data'])) {
            $result[]='data';
        }

        return $result;
    }

    /**
     * Write backup XML for this item.
     * @param xml_backup &$backup Backup handler
     * @param module_resourcepage &$rp Resourcepage object
     * @param bool $sitefiles True to include site files
     */
    public function backup(&$backup,&$rp, &$mainrow, $sitefiles) {
        global $CFG;
        $backup->tag_start('THING'); // See explanation in resourcepage_container
        $backup->tag_full('THINGTYPE','ITEM', false);
        $backup->tag_full('ITEMID',$this->fields['item'], false);
        // Alias items are only backed-up as such if the base item has a plugininfo field
        // (used to verify identity on restore)
        if($this->fields['basedonitem'] && strlen($this->fields['baseplugininfo'])>0) {
            $backup->tag_start('ALIAS');
            $backup->tag_full('ID',$this->fields['basedonitem']);
            $backup->tag_full('PLUGININFO',$this->fields['baseplugininfo']);
            $backup->tag_full('DEFERFIELDS',implode(',',$this->get_deferring_fields()));
            $backup->tag_end('ALIAS');
            // Restore process will check whether this item (ID) exists.
            // If it exists and seems to match then it'll be restored as
            // an alias. Otherwise it'll be restored as a normal item.
        }

        $this->backup_fields($backup,array(
            'itemtype','editable','livedate','removedate','showto',
            'title','description','plugininfo','forcehide','weblink',
            'placeholder','crosslink','headinglevel','hidden','options','rights','data'));

        $backup->tag_start('FLAGS');
        foreach($this->flags as $flag=>$value) {
            $backup->tag_full('FLAG-'.strtoupper($value),$flag, false);
        }
        foreach($this->baseflags as $flag=>$value) {
            $backup->tag_full('FLAG-B',$flag, false);
        }
        $backup->tag_end('FLAGS');

        $backup->tag_start('FILES');
        foreach($this->get_files() as $file) {
            $backup->tag_start('FILE');

            $filepath=$file->get_filepath();
            $matches=array();
            if(preg_match('/^'.$backup->get_courseid().'\/(.*)$/',$filepath,$matches)) {
                $filepath='%%COURSEID%%/'.$matches[1];
                // Course files other than moddata don't need to be copied as they are
                // stored anyway.
                if(preg_match('/^%%COURSEID%%\/moddata\/resourcepage\/(.*)$/',$filepath,$matches)) {
                    $backup->copy_module_file('resourcepage',$matches[1]);
                }
            } else {
                // Remember where it was originally
                $backup->tag_full('ORIGINALFILEPATH',$filepath);
                // But also store file in case it isn't available on restore,
                // if backup of site files is selected
                if($sitefiles) {
                    $folder=$CFG->dataroot.'/'.$backup->get_courseid().'/moddata/resourcepage/';
                    $name=basename($filepath);
                    $index=2;
                    while(file_exists($folder.$name)) {
                        if($index>2) {
                            // Get rid of n_
                            $name=substr($name,strpos($name,'_')+1);
                        }
                        // Add numerical prefix
                        $name=$index.'_'.$name;
                        $index++;
                    }
                    $backup->copy_file($CFG->dataroot.'/'.$filepath,
                        'moddata/resourcepage/'.$name);
                    $filepath=$backup->get_courseid().'/moddata/resourcepage/'.$name;
                }
            }
            $backup->tag_full('FILEPATH',$filepath);
            $backup->tag_full('MIMETYPE',$file->get_mime_type());
            $backup->tag_full('SIZE',$file->get_size());
            if($file->get_from_base()) {
                $backup->tag_full('FROMBASE','');
            }
            $backup->tag_end('FILE');
        }
        $backup->tag_end('FILES');

        // Placeholders need special handling...
        if($placeholder=$this->get_field('placeholder')) {
            // Placeholder items table
            $backup->tag_start('PLACEHOLDERITEMS');
            foreach($rp->get_placeholder_added_items_plus($this->get_item(),'modprefix_items','id')
                as $itemid=>$addeditem) {
                $backup->tag_start('ADDEDITEM');
                $backup->tag_full('ID',$itemid);
                $backup->tag_full('PLUGININFO',$addeditem->plugininfo);
                $backup->tag_end('ADDEDITEM');
                // The data fields here are only used to match the item. If any of these items
                // doesn't exist or doesn't match, then the placeholder will be ditched (to
                // reduce risk of adding items twice).
            }
            $backup->tag_end('PLACEHOLDERITEMS');

            // Extension settings
            $rp->get_extension_for_placeholder($placeholder)->backup($backup,$rp,$placeholder,$this->get_item());
        }

        $backup->tag_end('THING');
    }

    private function backup_fields(&$backup,$fields) {
        foreach($fields as $field) {
            $backup->tag_full_notnull(strtoupper($field),
                $this->get_field(strtolower($field)), false);
        }
    }

    public static function restore($rp,$restoresettings,$containerid,$xml) {
        $itemtype=self::restore_get_field($xml,'ITEMTYPE');
        if($itemtype == 'crosslink') {
           if(!isset($restoresettings->dbversion)) {
               if(!defined('RESTORE_SILENTLY')){
                    mtrace("--- WARNING: Crosslink cannot be restored. This backup was created from an earlier version of the VLE ---");
               }
               return;
           }
        }

        $doingalias=false;
        if(array_key_exists('ALIAS',$xml)) {
            $aliasxml=$xml['ALIAS'][0]['#'];
            // See if original item is there...
            $baseid=$aliasxml['ID'][0]['#'];
            $baseplugininfo=$aliasxml['PLUGININFO'][0]['#'];
            $rs=$rp->do_sql(
                "SELECT count(id) AS count
                FROM modprefix_items
                WHERE id=$baseid AND plugininfo=".$rp->c($baseplugininfo));
            if($rs->fields['count']==1) {
                // Original item is still there, so link this one to it

                // Get list of deferring fields
                $deferfields=array_flip(explode(',',$aliasxml['DEFERFIELDS'][0]['#']));

                // Move crosslink to pluginfo field to avoid FK constraints
                // Note: Will be relinked after restore (restore_decode_links())
                $plugininfo = self::restore_get_field($xml,'PLUGININFO',$deferfields);
                $crosslink = self::restore_get_field($xml,'CROSSLINK',$deferfields);
                if ($itemtype == 'crosslink') {
                    $plugininfo = $crosslink;
                    $crosslink = null;
                }

                // Get old level/new headinglevel field
                $headinglevel = !array_key_exists('LEVEL', $xml) ? 'HEADINGLEVEL' : 'LEVEL';

                // Add alias item
                $itemid=$rp->add_item(
                    null,
                    self::restore_get_field($xml,'EDITABLE',$deferfields),
                    self::restore_get_field($xml,'LIVEDATE',$deferfields),
                    self::restore_get_field($xml,'REMOVEDATE',$deferfields),
                    self::restore_get_field($xml,'SHOWTO',$deferfields),
                    self::restore_get_field($xml,'TITLE',$deferfields),
                    self::restore_get_field($xml,'DESCRIPTION',$deferfields),
                    $plugininfo,
                    self::restore_get_field($xml,'WEBLINK',$deferfields),
                    self::restore_get_field($xml,'PLACEHOLDER',$deferfields),
                    $baseid,
                    $crosslink,
                    self::restore_get_field($xml,$headinglevel,$deferfields),
                    self::restore_get_field($xml,'OPTIONS',$deferfields),
                    self::restore_get_field($xml,'RIGHTS',$deferfields),
                    self::restore_get_field($xml,'DATA',$deferfields));

                $doingalias=true;
            }
            // If original item isn't there, treat as a normal item
        }

        $phadded=null; $placeholder=null;
        if($itemtype=='placeholder') {
            $placeholder=self::restore_get_field($xml,'PLACEHOLDER');

            // If any of the added items are missing, we don't restore
            // the placeholder.
            $missing=false;
            if(isset($xml['PLACEHOLDERITEMS'][0]['#']['ADDEDITEM'])) {
                $phadded=$xml['PLACEHOLDERITEMS'][0]['#']['ADDEDITEM'];
                foreach($phadded as $addeditem) {
                    $addedid=$addeditem['#']['ID'][0]['#'];
                    $addedplugininfo=$addeditem['#']['PLUGININFO'][0]['#'];

                    // Find item (doing this one at a time is inefficient
                    // but what-ever)
                    $rs=$rp->do_sql("SELECT COUNT(id) AS count FROM modprefix_items
                        WHERE id=$addedid AND plugininfo=".$rp->c($addedplugininfo));
                    if($rs->fields['count']==0) {
                        $missing=true;
                        break;
                    }
                }
            }

            if($missing) {
                return; // Not restoring it
            }
            // OK, continue...
        }

        if(!$doingalias) {

            // Move crosslink to pluginfo field to avoid FK constraints
            // Note: Will be relinked after restore (restore_decode_links())
            $plugininfo = self::restore_get_field($xml,'PLUGININFO');
            $crosslink = self::restore_get_field($xml,'CROSSLINK');
            if ($itemtype == 'crosslink') {
                $plugininfo = $crosslink;
                $crosslink = null;
            }

            // Get old level/new headinglevel field
            $headinglevel = !array_key_exists('LEVEL', $xml) ? 'HEADINGLEVEL' : 'LEVEL';

            // Add item itself
            $itemid=$rp->add_item(
                $itemtype,
                self::restore_get_field($xml,'EDITABLE'),
                self::restore_get_field($xml,'LIVEDATE'),
                self::restore_get_field($xml,'REMOVEDATE'),
                self::restore_get_field($xml,'SHOWTO'),
                self::restore_get_field($xml,'TITLE'),
                restore_decode_absolute_links(self::restore_get_field($xml,'DESCRIPTION')),
                $plugininfo,
                self::restore_get_field($xml,'WEBLINK'),
                $placeholder,
                null,
                $crosslink,
                self::restore_get_field($xml,$headinglevel),
                self::restore_get_field($xml,'OPTIONS'),
                self::restore_get_field($xml,'RIGHTS'),
                self::restore_get_field($xml,'DATA'));
        }

        if($itemtype=='placeholder') {
            // Put back placeholder items
            if(isset($phadded)) {
                foreach($phadded as $addeditem) {
                    $addedid=$addeditem['#']['ID'][0]['#'];
                    $rp->add_placeholder_item($itemid,$addedid,null,null,null,true);
                }
            }

            // Restore placeholder settings
            $rp->get_extension_for_placeholder($placeholder)->restore($restoresettings,$rp,$itemid,$xml);
        }

        // A note on flag handling/alias: if not doing an alias we
        // intend to make the restore identical in effect to the
        // previous state. If doing alias, we just intend to give it
        // the same Y or N flags (regardless of whether changes in
        // base flags may have made them superfluous).

        // Add 'yes' flags regardless
        $yflags=array();
        if(isset($xml['FLAGS'][0]['#']['FLAG-Y'])) {
            foreach($xml['FLAGS'][0]['#']['FLAG-Y'] as $flagxml) {
                $flagname=$flagxml['#'];
                $yflags[]=$flagname;
                $rp->add_item_flag($itemid,$flagname);
            }
        }
        if($doingalias) {
            // Only add the 'no' flags if doing an alias
            if(isset($xml['FLAGS'][0]['#']['FLAG-N'])) {
                foreach($xml['FLAGS'][0]['#']['FLAG-N'] as $flagxml) {
                    $flagname=$flagxml['#'];
                    $rp->add_item_flag($itemid,$flagname,false);
                }
            }
        } else {
            // And only add the 'base' flags if not doing an alias
            if(isset($xml['FLAGS'][0]['#']['FLAG-B'])) {
                foreach($xml['FLAGS'][0]['#']['FLAG-B'] as $flagxml) {
                    $flagname=$flagxml['#'];
                    if(!in_array($flagname,$yflags)) {
                        $rp->add_item_flag($itemid,$flagname);
                    }
                }
            }
        }

        // Add files
        global $CFG;
        if(isset($xml['FILES'][0]['#']['FILE'])) {
            foreach($xml['FILES'][0]['#']['FILE'] as $fxmlroot) {
                $filexml=$fxmlroot['#'];
                // Skip files that are owned by base item
                if(array_key_exists('FROMBASE',$filexml) && $doingalias) {
                    continue;
                }
                // Check for files that were stored outside the course
                $originalfilepath=self::restore_get_field($filexml,'ORIGINALFILEPATH');
                if($originalfilepath && file_exists($CFG->dataroot.'/'.$originalfilepath)) {
                    // File was still there so just link it again.
                    $filepath=$originalfilepath;
                } else { // File that was stored in course, or wasn't but isn't there any more
                    $filepath=self::restore_get_field($filexml,'FILEPATH');
                    $filepath=preg_replace('/^%%COURSEID%%/',$restoresettings->course_id,$filepath);
                    // Files in moddata need to be copied. So do 'site' files.
                    // Other course files if used are ok.
                    if(preg_match('/^'.$restoresettings->course_id.'\/moddata\/resourcepage\/(.*)$/',
                        $filepath) || $originalfilepath) {
                        // If it's a 'site' file but we're not copying site files...
                        if($originalfilepath && !$restoresettings->site_files) {
                            continue;
                        }

                        // Make target folder in case it's not there
                        $targetfolder=$CFG->dataroot.'/'.dirname($filepath);
                        if(!mkdir_recursive($targetfolder)) {
                            throw new Exception("Failed to create folder $targetfolder");
                        }
                        // Copy file
                        $sourcefile=
                            $CFG->dataroot.'/temp/backup/'.$restoresettings->backup_unique_code.
                            '/moddata/resourcepage/'.basename($filepath);
                        if(!backup_copy_file(
                            $sourcefile,
                            $CFG->dataroot.'/'.$filepath)) {
                            throw new Exception("Failed to copy file $sourcefile");
                        }
                    }
                }
                $rp->add_item_file($itemid,
                    $filepath,
                    self::restore_get_field($filexml,'MIMETYPE'),
                    self::restore_get_field($filexml,'SIZE'),
                    $filepath);
            }
        }
        if (self::restore_get_field($xml,'ITEMID')){
            $oldid = self::restore_get_field($xml,'ITEMID');
            backup_putid($restoresettings->backup_unique_code, "resourcepage_items", $oldid, $itemid);
        }
        $rp->add_container_item($containerid,$itemid,
            self::restore_get_field($xml,'HIDDEN') ? true : false);
    }

    private static function restore_get_field($xml,$field,$exceptifinhere=false) {
        if(!array_key_exists($field,$xml) ||
            ($exceptifinhere && array_key_exists(strtolower($field),$exceptifinhere))) {
            return null;
        }
        return restore_decode_absolute_links($xml[$field][0]['#']);
    }



    private function display_rss_header($mainicon,$iconflags,$url,$title,$nolinks,$istext=false, $cm=NULL) {

        $content = '';

        // Ensure URL is safe
        if(preg_match('/[<>\'"]/',$url)) {
            $url='http://in.valid/url/';
        }

        if(!$title) {
            // Don't print empty titles
            return;

        } else {

            // print the title

            $content = $content.'<title>'.htmlspecialchars(self::get_title_as_text($title)).'</title>';

        }

        if($nolinks || !$url) {
            // print empty link tag - leave blank
            // $content = $content.'<link/>';
        } else {
            $content = $content.'<link>'.htmlspecialchars($url).'</link>';
        }

        return $content;

    }

    /**
     * Checks if URL is one of those that is broken.
     * @param string $url URL to fix
     * @return string The fixed URL
     */
    private function check_weblink($url)
    {
        if (function_exists('repair_url')) {
            $url = repair_url($url);
        }
        return $url;
    }

    /**
     * Displays the main content of a web link item.
     * @param bool $editing If true, display fields for inline editing of this item.
     * @param bool $otheritem If true, turn off links as other item is being edited
     */
    private function display_rss_weblink($otheritem) {

        $content = '';
        $url=$this->get_field('weblink');
        $url=$this->check_weblink($url);

            $content = $content.$this->display_rss_header(
                $this->get_link_icon($url),true,
                $url,
                $this->get_field('title'),
                $otheritem);

            $content = $content.$this->display_rss_description();

        return $content;

    }


    /**
     * Displays the main content of a file item.
     * @param bool $editing If true, display fields for inline editing of this item.
     * @param int $courseid ID of course
     * @param bool $otheritem If true, turn off links as other item is being edited
     */
    private function display_rss_file($editing,$courseid,$otheritem, $cm=NULL) {

        $content = '';

            // OK are there multiple formats?
            $gotmultiple=count($this->files) > 1;
            $gotany=count($this->files) > 0;

            // For multiple files (and if file isn't loaded yet) we make the title not be a link and have no icon
            if($gotmultiple || !$gotany) {
                $content = $content.$this->display_rss_header(
                    false,true,
                    false,
                    $this->get_field('title'),
                    $otheritem, false, $cm);
            } else { // Single files get icon and link
                $file=$this->files[0];
                $content = $content.$this->display_rss_header(
                    mimeinfo_from_type("icon",$file->get_mime_type()),true,
                    $this->get_link_path($courseid,$file),
                    $this->get_field('title'),
                    $otheritem, false, $cm);
            }

            // Description comes next
            $content = $content.$this->display_rss_description();

        return $content;

    }


    private function display_rss_description() {

        $content = '';
        $description=$this->get_field('description');
        // If it's empty (or has nothing except tags), don't output it
        if(preg_replace('/\s|<.*?>/','',$description)!='') {

         $content = $content.'<description>'.htmlspecialchars($this->get_field('description')).'</description>';

        }

        return $content;

    }


    /**
     * Displays the main content of a text item.
     * @param bool $editing If true, display fields for inline editing of this item.
     */
    function display_rss_text($editing) {

        $content = '';

        $content = $content.$this->display_rss_header(false,false,false,
                self::$this->get_field('title'),false,true);

        $content = $content.$this->display_rss_description();

        return $content;
    }


    /**
     * Displays the main content of a crosslink item.
     * @param bool $editing If true, display fields for inline editing of this item.
     * @param int $courseid ID of course
     * @param int $moduleid ID of this module
     * @param bool $otheritem If true, turn off links as other item is being edited
     */
    function display_rss_crosslink($editing,$courseid,$moduleid,$otheritem) {

        $content = '';

        $content = $content.$this->display_rss_header(false,false,
                'view.php?a='.$this->get_field('crosslink'),
                $this->fields['crosslinktitle'],
                $otheritem);

        return $content;

    }


    /**
     * Displays the main content of a placeholder item.
     * @param object $display Placeholder display details obtained using get_placeholder_display_details
     */
    function display_rss_placeholder($courseid,$display) {

        $content = '';
        $placeholder=$this->get_field('placeholder');
        $this->display_rss_header(false,false,false,
            $display->title,
            false);
        if(preg_replace('/\s|<.*?>/','',$display->description)!='') {

            $content = $content.$this->display_rss_description();
        }

        return $content;

    }

    //ou-specific begins
    
    /**
     * Displays the content of a podcast item
     *
     * @param object $course Object representing row from Moodle course table
     */
    
    public function display_rss_podcast($course){
    	global $CFG;
    	
    	$live            = $this->get_field('livedate');
        $remove          = $this->get_field('removedate');
        $livetime        = module_resourcepage::convert_date($course->startdate,$live);
        $removetime      = module_resourcepage::convert_date($course->startdate,$remove);
        $beforelivedate  = (!is_null($live) && time() < $livetime);
        $afterremovedate = (!is_null($remove) && time() >= $removetime);
    	
        if($beforelivedate || $afterremovedate){
        	return;
        }
    	
        $files = $this->get_files();  

        $url = $CFG->wwwroot . '/mod/resourcepage/mp3.php/' . $files[0]->get_filepath();
        
    	$content  = '<item>';
    	$content .=	'<title>' . $this->get_field('title') . '</title>';
    	$content .= '<pubDate>' . date('D, d M Y', $livetime) . '</pubDate>';
    	$content .= '<enclosure url="' . $url . '" type="' . $files[0]->get_mime_type() . '"/>';
    	$content .= '<guid isPermaLink="false">' . $url . '</guid>';
    	$content .= '<link>' . $url . '</link>';
    	$content .= '<media:content url="' . $url . '" fileSize="' . $files[0]->get_size() . '" type="' . $files[0]->get_mime_type() . '" medium="audio" expression="full"/>';
    	
    	$description = $this->display_rss_description();

    	$content .= $description;
    	    	    	
    	$description = substr($description,13);
    	$description = substr($description,0,-14);

    	$content .= '<itunes:summary>' . $description . '</itunes:summary>';
		
    	$desc_sp = split(" ",$description);
    	
    	if(sizeof($desc_sp)>45){
    		$desc_sp = splice($desc_split,44);
    	}
    	
    	$content .= '<itunes:subtitle>' . implode(" ",$desc_sp) . '...</itunes:subtitle>';
		$content .= '<itunes:author>The Open University</itunes:author>';
		$content .= '<itunes:duration>0:15</itunes:duration>';
    	$content .= '</item>';
		
    	return $content;
    	
    }
    
    //ou-specific ends

    /**
     * Displays as RSS.
     * @param object $course Object representing row from Moodle course table
     * @param object $cm Course module table row
     * @param boolean $editmode True when page is in edit mode (or edit item mode)
     * @param boolean $edititem Set to 'item' ID when page is in edit item mode, null otherwise
     * @param boolean $ignored Unnecessary parameter required so it matches the resourcepage_container
     *   method
     * @param boolean $itemcontrols If false, an item even in edit mode should not be editable (though
     *   it should still display admin information)
     */
    public function display_as_rss($course,$cm,$editmode=false,$edititem=null,$ignored,$itemcontrols=true) {

        // Get info we need elsewhere  - not all necessary but may be used else where.

        $hidden=$this->is_hidden() || $this->get_bool('forcehide');
        $editingitem=$edititem == $this->get_field('item');
        $itemid=$this->fields['item'];
        $sesskey=sesskey();
        $parentcontainer=$this->parent->get_container();
        $itemtype=$this->get_field('itemtype');
        $filewithnofiles=$itemtype=='file' && count($this->files)==0;
        $live=$this->get_field('livedate');
        $remove=$this->get_field('removedate');
        $livetime=module_resourcepage::convert_date($course->startdate,$live);
        $removetime=module_resourcepage::convert_date($course->startdate,$remove);
        $beforelivedate=(!is_null($live) && time() < $livetime);
        $afterremovedate=(!is_null($remove) && time() >= $removetime);
        $showto=$this->get_field('showto');
        if($showto==null) {
            $showto='';
        }


        $content = '';

        // Begin item
        $content = $content.'<item>';

        // Do main part depending on type
        switch($itemtype) {
            case 'weblink' :
                $content = $content.$this->display_rss_weblink($edititem);
                break;
            case 'file' :
                $content = $content.$this->display_rss_file($editingitem,$course->id,$edititem, $cm);
                break;
            case 'placeholder' :
                    if(empty($phdisplay)) {
                        $phdisplay=module_resourcepage::$inst->get_placeholder_display_details(
                            $this->fields['placeholder'],$itemid);
                        if(!$phdisplay) {

                            // ignore
                        }
                    }
                    $content = $content.$this->display_rss_placeholder($course->id,$phdisplay);

                break;
            case 'text' :
                $content = $content.$this->display_rss_text($editingitem);
                break;
            case 'crosslink' :
                $content = $content.$this->display_rss_crosslink($editingitem,$course->id,$cm->instance,$edititem);
                break;
            case 'forumlink' :
                // do nothing for the moment
                // TODO Alan #bug 1430
                break;
            case 'reference' :
                //for some reason rss feed is not utf-8? WHY!!
                $this->fields['title']=mb_convert_encoding($this->fields['title'], 'ISO-8859-15', 'UTF-8');
                if($this->fields['weblink']!=''){
                    $content = $content.$this->display_rss_weblink($edititem);
                }else{
                    $content = $content.$this->display_atom_text($editingitem);
                }
                break;
            default:
                throw new Exception('Unknown item type in database: '.
                    $this->get_field('itemtype'));
        }


        // Close item


        $content = $content.'</item>';

        return $content;

    }



    private function display_atom_header($mainicon,$iconflags,$url,$title,$nolinks,$istext=false, $cm=NULL) {

        $content = '';

        // Ensure URL is safe
        if(preg_match('/[<>\'"]/',$url)) {
            $url='http://in.valid/url/';
        }

        if(!$title) {
            // Don't print empty titles
            return;

        } else {

            // print the title

            $content = $content.'<title>'.htmlspecialchars(self::get_title_as_text($title)).'</title>';

        }

        if($nolinks || !$url) {
            // print empty link tag
            $content = $content.'<link/>';
        } else {
            $content = $content.'<link href="'.$url.'"/>';
        }


        return $content;


    }



    /**
     * Displays the main content of a web link item.
     * @param bool $editing If true, display fields for inline editing of this item.
     * @param bool $otheritem If true, turn off links as other item is being edited
     */
    private function display_atom_weblink($otheritem) {

        $content = '';
        $url=$this->get_field('weblink');
        $url=$this->check_weblink($url);

            $content = $content.$this->display_atom_header(
                $this->get_link_icon($url),true,
                $url,
                htmlspecialchars($this->get_field('title')),
                $otheritem);

            $content = $content.$this->display_atom_summary();


            return $content;

    }


    /**
     * Displays the main content of a file item.
     * @param bool $editing If true, display fields for inline editing of this item.
     * @param int $courseid ID of course
     * @param bool $otheritem If true, turn off links as other item is being edited
     */
    private function display_atom_file($editing,$courseid,$otheritem, $cm=NULL) {

        $content = '';

            // OK are there multiple formats?
            $gotmultiple=count($this->files) > 1;
            $gotany=count($this->files) > 0;

            // For multiple files (and if file isn't loaded yet) we make the title not be a link and have no icon
            if($gotmultiple || !$gotany) {
                $content = $content.$this->display_atom_header(
                    false,true,
                    false,
                    htmlspecialchars($this->get_field('title')),
                    $otheritem, false, $cm);
            } else { // Single files get icon and link
                $file=$this->files[0];
                $content = $content.$this->display_atom_header(
                    mimeinfo_from_type("icon",$file->get_mime_type()),true,
                    $this->get_link_path($courseid,$file),
                    htmlspecialchars($this->get_field('title')),
                    $otheritem, false, $cm);
            }

            // Description comes next
            $content = $content.$this->display_atom_summary();

            return $content;

    }


    private function display_atom_summary() {

        $content = '';

        $description=$this->get_field('description');
        // If it's empty (or has nothing except tags), don't output it
        if(preg_replace('/\s|<.*?>/','',$description)!='') {
            // printf('');

                $content = $content.'<summary>'.$this->get_field('description').'</summary>';

        }

        return $content;
    }


    /**
     * Displays the main content of a text item.
     * @param bool $editing If true, display fields for inline editing of this item.
     */
    function display_atom_text($editing) {

        $content = '';

            $content = $content.$this->display_atom_header(false,false,false,
                htmlspecialchars($this->get_field('title')),false,true);
            $content = $content.$this->display_atom_summary();

            return $content;
    }


    /**
     * Displays the main content of a crosslink item.
     * @param bool $editing If true, display fields for inline editing of this item.
     * @param int $courseid ID of course
     * @param int $moduleid ID of this module
     * @param bool $otheritem If true, turn off links as other item is being edited
     */
    function display_atom_crosslink($editing,$courseid,$moduleid,$otheritem) {

        $content = '';

            $content = $content.$this->display_atom_header(false,false,
                'view.php?a='.$this->get_field('crosslink'),
                htmlspecialchars($this->fields['crosslinktitle']),
                $otheritem);

            return $content;

    }


    /**
     * Displays the main content of a placeholder item.
     * @param object $display Placeholder display details obtained using get_placeholder_display_details
     */
    function display_atom_placeholder($courseid,$display) {

        $content = '';

        $placeholder=$this->get_field('placeholder');

        $content = $content.$this->display_atom_header(false,false,false,
            htmlspecialchars($display->title),
            false);
        if(preg_replace('/\s|<.*?>/','',$display->description)!='') {

            $content = $content.$this->display_atom_summary();
        }

        return $content;

    }


    /**
     * Displays as Atom.
     * @param object $course Object representing row from Moodle course table
     * @param object $cm Course module table row
     * @param boolean $editmode True when page is in edit mode (or edit item mode)
     * @param boolean $edititem Set to 'item' ID when page is in edit item mode, null otherwise
     * @param boolean $ignored Unnecessary parameter required so it matches the resourcepage_container
     *   method
     * @param boolean $itemcontrols If false, an item even in edit mode should not be editable (though
     *   it should still display admin information)
     */
    public function display_as_atom($course,$cm,$editmode=false,$edititem=null,$ignored,$itemcontrols=true) {

        // Get info we need elsewhere  - not all necessary but may be used else where.

        $hidden=$this->is_hidden() || $this->get_bool('forcehide');
        $editingitem=$edititem == $this->get_field('item');
        $itemid=$this->fields['item'];
        $sesskey=sesskey();
        $parentcontainer=$this->parent->get_container();
        $itemtype=$this->get_field('itemtype');
        $filewithnofiles=$itemtype=='file' && count($this->files)==0;
        $live=$this->get_field('livedate');
        $remove=$this->get_field('removedate');
        $livetime=module_resourcepage::convert_date($course->startdate,$live);
        $removetime=module_resourcepage::convert_date($course->startdate,$remove);
        $beforelivedate=(!is_null($live) && time() < $livetime);
        $afterremovedate=(!is_null($remove) && time() >= $removetime);
        $showto=$this->get_field('showto');
        if($showto==null) {
            $showto='';
        }


        $content = '';

        // Begin item
        $content = $content.'<entry>';

        // Do main part depending on type
        switch($itemtype) {
            case 'weblink' :
                $content = $content.$this->display_atom_weblink($edititem);
                break;
            case 'file' :
                $content = $content.$this->display_atom_file($editingitem,$course->id,$edititem, $cm);
                break;
            case 'placeholder' :
                    if(empty($phdisplay)) {
                        $phdisplay=module_resourcepage::$inst->get_placeholder_display_details(
                            $this->fields['placeholder'],$itemid);
                        if(!$phdisplay) {

                            // ignore
                        }
                    }
                    $content = $content.$this->display_atom_placeholder($course->id,$phdisplay);

                break;
            case 'text' :
                $content = $content.$this->display_atom_text($editingitem);
                break;
            case 'crosslink' :
                $content = $content.$this->display_atom_crosslink($editingitem,$course->id,$cm->instance,$edititem);
                break;
            case 'forumlink' :
                // do nothing for the moment
                // TODO Alan #bug 1430
                break;
            case 'reference' :
                //for some reason atom feed is not utf-8? WHY!!
                $this->fields['title']=mb_convert_encoding($this->fields['title'], 'ISO-8859-15', 'UTF-8');
                if($this->fields['weblink']!=''){
                    $content = $content.$this->display_atom_weblink($edititem);
                }else{
                    $content = $content.$this->display_atom_text($editingitem);
                }
                break;
            default:
                throw new Exception('Unknown item type in database: '.
                    $this->get_field('itemtype'));
        }


        // Close item


        $content = $content.'</entry>';

        return $content;

    }

    /**
    * check to see whether files attached to an item are empty
    * @return boolean True if files empty or don't have a file path,
    * otherwise returns false
    */
    public function is_item_files_empty() {

    $itemempty = false; // assume item is not hidden

        $filesarray = $this->get_files();
        $count = count($filesarray);
        if($count> 0) {
            for($i = 0; $i < $count; $i++){
                $filepath = $filesarray[$i]->get_filepath();
                if(empty($filepath)) {
                    $itemempty = true;
                } else {
                    // item is not empty - so get out of here
                    $itemempty = false;
                    break;
                 }

            } // endfor

        } else {
            $itemempty = true;
        }

        return $itemempty;

    }


   /**
    * Checks to see whether an item is considered to be empty. Empty items do
    * not display to students.
    * @param object $course Course object
    * @return boolean True if item is considered empty
    */
    public function is_hidden_from_students($course) {
        global $CFG;

        // 'hidden' and 'forcehide' flags
        $hidden=$this->is_hidden() || $this->get_bool('forcehide');
        if($hidden) {
            return true;
        }

        // dates, in days relative to course start
        $live = $this->get_field('livedate');
        $remove = $this->get_field('removedate');
        $livetime = module_resourcepage::convert_date($course->startdate, $live);
        $removetime = module_resourcepage::convert_date($course->startdate, $remove);
        $beforelivedate = (!is_null($live) && time() < $livetime);
        $afterremovedate = (!is_null($remove) && time() >= $removetime);
        if($beforelivedate || $afterremovedate) {
            return true;
        }

        // user permissions
        $showto = $this->get_field('showto');
        if (defined('AUTH_SAMS') && AUTH_SAMS == $CFG->auth && $showto) {
            if(!class_exists('SamsAuth') || !SamsAuth::$inst->match_authids($showto)) {
                return true;
            }
        }

        // Do type-specific checks
        $itemtype = $this->get_field('itemtype');
        switch($itemtype) {
            case 'weblink' :
                $weblink = $this->get_field('weblink');
                if (empty($weblink) || trim($weblink == 'http://')) {
                    // Link not set
                    return true;
                }
                break;
            case 'file' :
                // check to see actual file has been provided
                // needs to check if attached file array is empty
                if ($this->is_item_files_empty()) {
                    // No files
                    return true;
                }
                if (!$this->get_field('rights')) {
                    // Rights not cleared
                    return true;
                }
                break;
            case 'placeholder' :
                // Placeholders never show to students, so count them as empty
                return true;
            case 'text' :
                if ($this->get_field('description')===''
                    && $this->get_field('title')==='') {
                    // Text with no title/description
                    return true;
                }
                break;
            case 'crosslink' :
                $crosslink = $this->get_field('crosslink');
                if (empty($crosslink)) {
                    // Crosslink with no target
                    return true;
                }
                break;
            case 'forumlink' :
                $weblink = $this->get_field('weblink');
                if (empty($weblink)) {
                    // Forum link with no target
                    return true;
                }
                break;
            case 'reference' : 
        		     $data=$this->get_field('data');
        		    if(empty($data)){
        		        return true;
        		    }
        		break;
            default:
                throw new Exception('Unknown item type in database: '.$itemtype);
        }

        // If we get to here, it doesn't seem to be hidden
        return false;
    }
}

?>